import ctypes
import os.path as osp
from enum import Enum
import numpy as np


class VGrid(object):
    def __init__(self):
        self.dll_handle = ctypes.windll.LoadLibrary(osp.join(osp.dirname(__file__), "dll", "vgrid.dll"))
        self.TLog_DLL_Handle = ctypes.windll.LoadLibrary(osp.join(osp.dirname(__file__), "dll", "TLog.dll"))

        self.dll_handle.CreateVGridInstance.restype = ctypes.POINTER(ctypes.c_void_p)
        self.dll_handle.CreateVGridInstance.argtypes = []

        # self.dll_handle.DestroyVGridInstance.restype = ctypes.POINTER(ctypes.c_void_p)
        self.dll_handle.DestroyVGridInstance.argtypes = [ctypes.c_void_p]

        self.dll_handle.VGridInitialization.restype = ctypes.c_bool
        self.dll_handle.VGridInitialization.argtypes = [ctypes.c_void_p, ctypes.c_uint16, ctypes.c_uint16, ctypes.c_uint8]

        self.dll_handle.VGridImageProcess.restype = ctypes.c_bool
        self.dll_handle.VGridImageProcess.argtypes = [
            ctypes.c_void_p,
            np.ctypeslib.ndpointer(dtype=np.uint16), np.ctypeslib.ndpointer(dtype=np.uint16),       # in out
            ctypes.c_float, ctypes.c_float, ctypes.c_float,                                         # PDB
            ctypes.c_float, ctypes.c_float, ctypes.c_float,                                         # content bright, his
            ctypes.c_bool, ctypes.c_bool, ctypes.c_bool,                                            # 3Flag
            ctypes.c_int32, ctypes.c_int32,                                                         # cutW cutH
            ctypes.c_bool,                                                                          # low dose
            ctypes.c_int32, ctypes.c_int32, ctypes.c_int32,                                         # axq child body
            ctypes.c_int32, ctypes.c_int32,                                                         # FOV FrameRate
            ctypes.c_float, ctypes.c_float,                                                         # LAO_RAO CRA_CAU
            ctypes.c_uint32, ctypes.c_uint16, ctypes.c_bool                                         # frameID, playMode, maskReady
        ]

        self.TLog_DLL_Handle.destroy.argtypes = []

        self.instance = self.dll_handle.CreateVGridInstance()

    def Initialization(self, width, height, nBit=16):
        self.dll_handle.VGridInitialization(self.instance, width, height, nBit)

    def Process(self, pImgIn, pImgOut, PContrast, DContrast, BContrast,
                content, brightness, hisgamma, SNRFlag, lpSubFlag, histFlag,
                cutWidth, cutHeight, low_dose, acqMode, acqChildmode, bodyPart,
                Fov, FrameRate, LAO_RAO, CRA_CAU, frameID, PlayMode, MaskReady=False):
        return self.dll_handle.VGridImageProcess(self.instance, pImgIn, pImgOut, PContrast, DContrast, BContrast,
                content, brightness, hisgamma, SNRFlag, lpSubFlag, histFlag,
                cutWidth, cutHeight, low_dose, acqMode, acqChildmode, bodyPart,
                Fov, FrameRate, LAO_RAO, CRA_CAU, frameID, PlayMode, MaskReady
                                                 )

    def __del__(self):
        self.dll_handle.DestroyVGridInstance(self.instance)
        self.TLog_DLL_Handle.destroy()

class BodyPart(object):
    def __init__(self):
        self.cardiac = 1
        self.neurolgy = 2
        self.Peripheral = 3
        self.abdomen = 4
        self.thorax = 5